package com.b2mining.integration.xml;

import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.mapping.MappingException;
import org.jdom.CDATA;
import org.jdom.DocType;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;
import com.b2mining.integration.beans.Empresa;
import com.b2mining.integration.beans.Retention;
import com.b2mining.integration.beans.RetentionItem;
import com.b2mining.integration.beans.XMLBean;
import com.b2mining.integration.controllers.XMLEmpresasController;
//import com.b2mining.integration.db.RetentionDBMapper;
import com.b2mining.integration.helper.Constantes;
import com.b2mining.integration.helper.Helper;
import com.b2mining.integration.helper.RequiredElementHelper;
import com.b2mining.integration.mq.MQIntegrationMessage;

/**
 * Clase 
 * @since 28/06/2007
 * @author adminebiz <BR>
 * Analista Programador: Richard Linares
 */
public class RetentionXMLMapper extends XMLMapper{
	Logger log = Logger.getLogger(this.getClass());
	static RetentionXMLMapper controller;    
    Mapping map;
    
    
public void generateXML(XMLBean bean, Writer stream) throws XMLMapperException{
	
        log.debug("RetentionXMLMapper: Metodo : generateXML : INICIO");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constantes.DATEFORMAT);
        XMLOutputter outputter = new XMLOutputter();
        outputter.setNewlines(true);
        outputter.setIndent(Constantes.TAB);
        outputter.setEncoding(Constantes.ENCODING_XML);        
        Document doc = new Document();
        
        Retention retention = (Retention)bean;
		RetentionItem retentionItem = null;
		
        if(retention.getEstado().equals("X")){
        	 DocType dt = new DocType("CERTSTATUS", "ret_status_mq.dtd");
             Element element = null;
             doc.setDocType(dt);
             Element root = new Element("CERTSTATUS");
             doc.setRootElement(root);
             
             /*por Rhandy 11-05-2010*/
     		//String value="";
     		//CDATA cdata = null;
     		/**/
     		
     		if (retention.getSerieRetencion()!=null){
    			element = new Element("SerieRetencion");
    			element.setText(retention.getSerieRetencion());
    			log.info("Serie Retencion "+retention.getSerieRetencion());
    			root.addContent(element);			
    		}
     		
     		if (retention.getNumRetencion()!=null){
    			element = new Element("NumeroRetencion");
    			element.setText(retention.getNumRetencion());
    			log.info("NumRetencion  "+retention.getNumRetencion());
    			root.addContent(element);
    		}
     		
     		if (retention.getRucComprador()!=null){
    			element = new Element("RucComprador");
    			element.setText(retention.getRucComprador());
    			log.info("RucComprador  "+retention.getRucComprador());
    			root.addContent(element);
    		}
    		
    		if (retention.getRucProveedor()!=null){
    			element = new Element("RucProveedor");
    			element.setText(retention.getRucProveedor());
    			log.info("RucProveedor  "+retention.getRucProveedor());
    			root.addContent(element);
    		}
    		
     		if (retention.getFechaRetencion()!=null){
    			element = new Element("Fecha");
    			element.setText(simpleDateFormat.format(retention.getFechaRetencion()));
    			log.info("FechaRetencion  "+retention.getFechaRetencion());
    			root.addContent(element);
    		}
     		
    		if(retention.getEstado()!=null){
    			element = new Element("Estado");
    			element.setText(retention.getEstado());
    			log.info("Estado  "+retention.getEstado());
    			root.addContent(element);
    			log.info("===Estado XML  "+element.getText());
    		}
    		
        }else if(retention.getEstado().equals("")){

            DocType dt = new DocType("CERTUPLOAD", "ret_upload_mq.dtd");
            Element element = null;
            doc.setDocType(dt);
            Element root = new Element("CERTUPLOAD");
            doc.setRootElement(root);
    		
    		
    		/*por Rhandy 11-05-2010*/
    		String value="";
    		CDATA cdata = null;
    		/**/
    		
    		//RetentionDBMapper retentionDBMapper =new RetentionDBMapper();
            
    		if (retention.getSerieRetencion()!=null){
    			element = new Element("SerieRetencion");
    			element.setText(retention.getSerieRetencion());
    			log.debug("Serie Retencion "+retention.getSerieRetencion());
    			root.addContent(element);			
    		}
    		
    		if (retention.getNumRetencion()!=null){
    			element = new Element("NumeroRetencion");
    			element.setText(retention.getNumRetencion());
    			log.debug("NumRetencion  "+retention.getNumRetencion());
    			root.addContent(element);
    		}
    			
    		if (retention.getRucComprador()!=null){
    			element = new Element("RucComprador");
    			element.setText(retention.getRucComprador());
    			log.debug("RucComprador  "+retention.getRucComprador());
    			root.addContent(element);
    		}
    		
    		if (retention.getRucProveedor()!=null){
    			element = new Element("RucProveedor");
    			element.setText(retention.getRucProveedor());
    			log.debug("RucProveedor  "+retention.getRucProveedor());
    			root.addContent(element);
    		}
    		
    		if (retention.getRazonSocialProveedor()!=null){
//    			element = new Element("RazonSocialProveedor");
//    			element.setText(retention.getRazonSocialProveedor());
//    			log.debug("RazonSocialProveedor  "+retention.getRazonSocialProveedor());
//    			root.addContent(element);
    			
    			/*por Rhandy 11-05-2010 */
    			value=retention.getRazonSocialProveedor();
    			cdata = new CDATA(value);
    			element = new Element("RazonSocialProveedor");
    			element.addContent(cdata);
    			root.addContent(element);
    			/**/ 
    		}else{
    			element = new Element("RazonSocialProveedor");
    			element.setText("");
    			root.addContent(element);
    		}
    		
    		if (retention.getDireccionProveedor()!=null){
//    			element = new Element("DireccionProveedor");
//    			element.setText(retention.getDireccionProveedor());
//    			log.debug("DireccionProveedor  "+retention.getDireccionProveedor());
//    			root.addContent(element);
    			
    			/*por Rhandy 11-05-2010 */
    			value=retention.getDireccionProveedor();
    			cdata = new CDATA(value);
    			element = new Element("DireccionProveedor");
    			element.addContent(cdata);
    			root.addContent(element);
    			/**/
    			
    		}else{
    			element = new Element("DireccionProveedor");
    			element.setText("");
    			root.addContent(element);
    		}
    		
    		if (retention.getFechaRetencion()!=null){
    			element = new Element("Fecha");
    			element.setText(simpleDateFormat.format(retention.getFechaRetencion()));
    			log.debug("FechaRetencion  "+retention.getFechaRetencion());
    			root.addContent(element);
    		}
    		
    		if (retention.getItemCount()>0){
    			for (int i=0;i<retention.getItemCount();i++){
    				
    				//Inicio: Modificacion realizada por Miguel Lora Gurreonero el 26/11/2003
    				//Element elementOffering = new Element("OfferingProductCode");
    				Element elementItem = new Element("DetalleRetencion");
    				//Fin: Modificacion realizada por Miguel Lora Gurreonero el 26/11/2003
    				
    				retentionItem = (RetentionItem)retention.getItem(i);
    				
    				if (retentionItem.getTipoDocumento()!=null){
    					element = new Element("TipoDocumento");
    					element.setText(retentionItem.getTipoDocumento());
    					log.debug("TipoDocumento  "+retentionItem.getTipoDocumento());
    					elementItem.addContent(element);
    				} else{
    					element = new Element("TipoDocumento");
    					element.setText("");
    					elementItem.addContent(element);
    				}
    				
    				if (retentionItem.getTipoDocumento()!=null){
    					element = new Element("SerieDocumento");
    					element.setText(retentionItem.getSerieDocumento());
    					log.debug("SerieDocumento  "+retentionItem.getSerieDocumento());
    					elementItem.addContent(element);
    				} else{
    					element = new Element("SerieDocumento");
    					element.setText("");
    					elementItem.addContent(element);
    				}
    				if (retentionItem.getTipoDocumento()!=null){
    					element = new Element("NumeroDocumento");
    					element.setText(retentionItem.getNumeroDocumento());
    					log.debug("NumeroDocumento  "+retentionItem.getNumeroDocumento());
    					elementItem.addContent(element);
    				} else{
    					element = new Element("NumeroDocumento");
    					element.setText("");
    					elementItem.addContent(element);
    				}
    				if (retentionItem.getFechaDocumento()!=null){
    					element = new Element("FechaDocumento");
    					element.setText(simpleDateFormat.format(retentionItem.getFechaDocumento()));
    					log.debug("FechaDocumento  "+retentionItem.getFechaDocumento());
    					elementItem.addContent(element);
    				}else{
    					element = new Element("FechaDocumento");
    					element.setText("");
    					elementItem.addContent(element);
    				}

    				if(retentionItem.getMontoPago()!=null){
    					element = new Element("MontoPago");
    					element.setText(String.valueOf(retentionItem.getMontoPago().doubleValue()));
    					log.debug("MontoPago  "+retentionItem.getMontoPago());
    					elementItem.addContent(element);
    				}
    				else{
    					element = new Element("MontoPago");
    					element.setText("");
    					elementItem.addContent(element);
    				}

    				if(retentionItem.getMontoRetenido()!=null){
    					
    					
    					element = new Element("MontoRetenido");
    					element.setText(String.valueOf(retentionItem.getMontoRetenido().doubleValue()));
    					log.debug("MontoRetenido  "+retentionItem.getMontoRetenido());
    					elementItem.addContent(element);
    				}
    				else{
    					element = new Element("MontoRetenido");
    					element.setText("");
    					elementItem.addContent(element);
    				}

    				if(retentionItem.getMontoOrigen()!=null){
    					element = new Element("MontoOrigen");
    					element.setText(String.valueOf(retentionItem.getMontoOrigen().doubleValue()));
    					log.debug("MontoOrigen  "+retentionItem.getMontoOrigen());
    					elementItem.addContent(element);
    				}
    				
    				if (retentionItem.getMoneda()!=null){
    					element = new Element("Moneda");
    					element.setText(retentionItem.getMoneda());
    					log.debug("Moneda  "+retentionItem.getMoneda());
    					elementItem.addContent(element);
    				} else{
    					element = new Element("Moneda");
    					element.setText("");
    					elementItem.addContent(element);
    				}
    				
    				if(retentionItem.getNroDocERPItem()!=null){
    					element = new Element("NroDocERPItem");
    					element.setText(retentionItem.getNroDocERPItem());
    					log.debug("NroDocERPItem  "+retentionItem.getNroDocERPItem());
    					elementItem.addContent(element);
    				}
    				root.addContent(elementItem);
    			}
    		}
    		
    		if (retention.getTipoCambio()!=null){
    			element = new Element("TipoCambio");
    			element.setText(retention.getTipoCambio());
    			log.debug("TipoCambio  "+retention.getTipoCambio());
    			root.addContent(element);
    		}
    		
    		if (retention.getBanco()!=null){
    			element = new Element("Banco");
    			element.setText(retention.getBanco());
    			log.debug("Banco  "+retention.getBanco());
    			root.addContent(element);
    		}
    		
    		if (retention.getCorridaNumero()!=null){
    			element = new Element("CorridaNumero");
    			element.setText(retention.getCorridaNumero());
    			log.debug("CorridaNumero  "+retention.getCorridaNumero());
    			root.addContent(element);
    		}
    		
    		if(retention.getTotalMontoPago()!=null){
    			element = new Element("TotalMontoPago");
    			element.setText(String.valueOf(retention.getTotalMontoPago().doubleValue()));
    			log.debug("TotalMontoPago  "+retention.getTotalMontoPago());
    			root.addContent(element);
    		}
    		else{
    			element = new Element("TotalMontoPago");
    			element.setText("");
    			root.addContent(element);
    		}
    		
    		if(retention.getTotalMontoRetencion()!=null){
    			element = new Element("TotalMontoRetenido");
    			element.setText(String.valueOf(retention.getTotalMontoRetencion().doubleValue()));
    			log.debug("TotalMontoRetencion  "+retention.getTotalMontoRetencion());
    			root.addContent(element);
    		}
    		else{
    			element = new Element("TotalMontoRetenido");
    			element.setText("");
    			root.addContent(element);
    		}
    		
    		if (retention.getMoneda()!=null){
    			element = new Element("Moneda");
    			element.setText(retention.getMoneda());
    			log.debug("Moneda  "+retention.getMoneda());
    			root.addContent(element);
    		}else{
    			element = new Element("Moneda");
    			element.setText("");
    			root.addContent(element);
    		}
    		
    		if(retention.getTotalMontoOrigen()!=null){
    			element = new Element("TotalMontoOrigen");
    			element.setText(String.valueOf(retention.getTotalMontoOrigen().doubleValue()));
    			log.debug("TotalMontoOrigen  "+retention.getTotalMontoOrigen());
    			root.addContent(element);
    		}
    		
    		if(retention.getNroDocPagoERP()!=null){
    			element = new Element("NroDocPagoERP");
    			element.setText(retention.getNroDocPagoERP());
    			log.debug("NroDocPagoERP  "+retention.getNroDocPagoERP());
    			root.addContent(element);
    		}
    		
    		if(retention.getObs()!=null){
//    			element = new Element("Obs");
//    			element.setText(retention.getObs());
//    			log.debug("Obs  "+retention.getObs());
//    			root.addContent(element);
    			
    			/*por Rhandy 11-05-2010 */
    			value=retention.getObs();
    			cdata = new CDATA(value);
    			element = new Element("Obs");
    			element.addContent(cdata);
    			root.addContent(element);
    			/**/
    		}
    		
    		if(retention.getEstado()!=null){
    			element = new Element("Flag");
    			element.setText(retention.getEstado());
    			log.debug("Flag  "+retention.getEstado());
    			root.addContent(element);
    		}
    		
    		if(retention.getEstadoInicial()!=null){
    			element = new Element("EstadoInicial");
    			element.setText(retention.getEstadoInicial());
    			log.debug("EstadoInicial  "+retention.getEstadoInicial());
    			root.addContent(element);
    		}
    		
    		if(retention.getDireccionCliente()!=null){
    			element = new Element("DireccionCliente");
    			element.setText(retention.getDireccionCliente());
    			log.debug("DireccionCliente  "+retention.getDireccionCliente());
    			root.addContent(element);
    		}
    		
    		if(retention.getPuestoExpedicion()!=null){
    			element = new Element("PuestoExpedicion");
    			element.setText(retention.getPuestoExpedicion());
    			log.debug("PuestoExpedicion  "+retention.getPuestoExpedicion());
    			root.addContent(element);
    		}
    		
    		if(retention.getRazonSocialCliente()!=null){
//    			element = new Element("RazonSocialCliente");
//    			element.setText(retention.getRazonSocialCliente());
//    			log.debug("RazonSocialCliente  "+retention.getRazonSocialCliente());
//    			root.addContent(element);
    			
    			/*por Rhandy 11-05-2010 */
    			value=retention.getRazonSocialCliente();
    			cdata = new CDATA(value);
    			element = new Element("RazonSocialCliente");
    			element.addContent(cdata);
    			root.addContent(element);
    			/**/
    		}
    		if(retention.getTelefonoCliente()!=null){
    			element = new Element("TelefonoCliente");
    			element.setText(retention.getTelefonoCliente());
    			log.debug("TelefonoCliente  "+retention.getTelefonoCliente());
    			root.addContent(element);
    		}
        }//del if de retention
        
		
		// aav Validacion de estructura y contenido
		XMLMapperException ex = new XMLMapperException();
		//log.debug("Antes de hacer la validacion del documento");
		validaDocumento(outputter.outputString(doc) , ex);
		log.debug(" QQQQQQQQQQQQQQ Contenido de ex : " + ex.getChildrenCount());
		if (ex.getChildrenCount()>0) {
			throw ex;
		}
			// .
			
        try
        {
            outputter.output(doc, stream);
            //log.debug("stream: " + stream.toString());   <<<<<<< para ver que hay en el stream 
            log.debug("XML de Retencion generado correctamente");
            stream.flush();
        }
        catch(Exception e)
        
        {	
            	throw new XMLMapperException("Error al tratar de escribir el XML Retention hacia la ruta de salida.");
        }
       
	
        log.debug("RetentionXMLMapper: Metodo : generateXML : FIN");
        
	}
	
	
	
	public static RetentionXMLMapper getInstance() throws IOException, MappingException{
	    if(controller==null){
	        controller = new RetentionXMLMapper();
	    }
	    return controller;
	}


	protected void validaContenido(Document doc , XMLMapperException ex) {
		
		Element docroot=null;    
        log.debug("RetentionXMLMapper: Metodo : validaContenido : INICIO");
		try {
			// Parsing the elements into beans:
                        
			docroot = doc.getRootElement();
			
			RequiredElementHelper reHelper= new RequiredElementHelper();
			String documentName = docroot.getName();
	
			String value=null;
			value =  reHelper.checkValue(docroot.getChild("SerieRetencion") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"SerieRetencion", value ))  {
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("SerieRetencion");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			value =  reHelper.checkValue(docroot.getChild("NumeroRetencion") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"NumeroRetencion", value ))  {
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("NumeroRetencion");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			value =  reHelper.checkValue(docroot.getChild("RucComprador") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"RucComprador", value ))  {
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("RucComprador");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			value =  reHelper.checkValue(docroot.getChild("RucProveedor") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"RucProveedor", value ))  {
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("RucProveedor");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			value =  reHelper.checkValue(docroot.getChild("RazonSocialProveedor") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"RazonSocialProveedor", value ))  {
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("RazonSocialProveedor");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}		
			value =  reHelper.checkValue(docroot.getChild("DireccionProveedor") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"DireccionProveedor", value ))  {
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("DireccionProveedor");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			value =  reHelper.checkValue(docroot.getChild("Fecha") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"Fecha", value ))  {
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("Fecha");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
		
			List retentionList = docroot.getChildren("DetalleRetencion");
			if ((retentionList==null||retentionList.size()==0) && reHelper.isRequiredGroup(documentName,"DetalleRetencion")) {
				MissingGroupException mge =		new MissingGroupException();
				mge.setElement("DetalleRetencion");
				mge.setParent(docroot);
				ex.addChild(mge);
			}
			if (retentionList!=null){
				for (int i=0;i<retentionList.size();i++){
					Element elementItem = (Element)retentionList.get(i);
					
					
		    	    value =  reHelper.checkValue( elementItem.getChild("TipoDocumento") );
		    	    //log.debug("campo "+value);
					if (!reHelper.isCorrect(documentName,"TipoDocumento", value )){
			            
			            MissingElementException mee = new MissingElementException();
			            mee.setElement("TipoDocumento");
			            mee.setParent(elementItem);
			            ex.addChild(mee);
					}
					
					value =  reHelper.checkValue( elementItem.getChild("SerieDocumento") );
					//log.debug("campo "+value);
					if (!reHelper.isCorrect(documentName,"SerieDocumento", value )){
			            
			            MissingElementException mee = new MissingElementException();
			            mee.setElement("SerieDocumento");
			            mee.setParent(elementItem);
			            ex.addChild(mee);
					}
					value =  reHelper.checkValue( elementItem.getChild("NumeroDocumento") );
					//log.debug("campo "+value);
					if (!reHelper.isCorrect(documentName,"NumeroDocumento", value )){
			            
			            MissingElementException mee = new MissingElementException();
			            mee.setElement("NumeroDocumento");
			            mee.setParent(elementItem);
			            ex.addChild(mee);
					}
					value =  reHelper.checkValue( elementItem.getChild("FechaDocumento") );
					//log.debug("campo "+value);
					if (!reHelper.isCorrect(documentName,"FechaDocumento", value )){
			            
			            MissingElementException mee = new MissingElementException();
			            mee.setElement("FechaDocumento");
			            mee.setParent(elementItem);
			            ex.addChild(mee);
					}
					value =  reHelper.checkValue( elementItem.getChild("MontoPago") );
					//log.debug("campo "+value);
					if (!reHelper.isCorrect(documentName,"MontoPago", value )){
			            
			            MissingElementException mee = new MissingElementException();
			            mee.setElement("MontoPago");
			            mee.setParent(elementItem);
			            ex.addChild(mee);
					}
					value =  reHelper.checkValue( elementItem.getChild("MontoRetenido") );
					//log.debug("campo "+value);
					if (!reHelper.isCorrect(documentName,"MontoRetenido", value )){
			            
			            MissingElementException mee = new MissingElementException();
			            mee.setElement("MontoRetenido");
			            mee.setParent(elementItem);
			            ex.addChild(mee);
					}
					value =  reHelper.checkValue( elementItem.getChild("MontoOrigen") );
					//log.debug("campo "+value);
					if (!reHelper.isCorrect(documentName,"MontoOrigen", value )){
			            
			            MissingElementException mee = new MissingElementException();
			            mee.setElement("MontoOrigen");
			            mee.setParent(elementItem);
			            ex.addChild(mee);
					}
					
					
					value =  reHelper.checkValue( elementItem.getChild("MonedaOrigen") );
					//log.debug("campo "+value);
					if (!reHelper.isCorrect(documentName,"Moneda", value )){
			            
			            MissingElementException mee = new MissingElementException();
			            mee.setElement("Moneda");
			            mee.setParent(elementItem);
			            ex.addChild(mee);
					}
					
				}
			}
			
			value =  reHelper.checkValue( docroot.getChild("TipoCambio") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"TipoCambio", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("TipoCambio");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			
			value =  reHelper.checkValue( docroot.getChild("Banco") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"Banco", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("Banco");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			
			value =  reHelper.checkValue( docroot.getChild("CorridaNumero") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"CorridaNumero", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("Banco");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			
			value =  reHelper.checkValue( docroot.getChild("TotalMontoPago") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"TotalMontoPago", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("TotalMontoPago");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			value =  reHelper.checkValue( docroot.getChild("TotalMontoRetenido") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"TotalMontoRetenido", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("TotalMontoRetenido");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			value =  reHelper.checkValue( docroot.getChild("Moneda") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"Moneda", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("Moneda");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			
			value =  reHelper.checkValue( docroot.getChild("TotalMontoOrigen") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"TotalMontoOrigen", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("TotalMontoOrigen");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			
			value =  reHelper.checkValue( docroot.getChild("NroDocERP") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"NroDocERP", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("NroDocERP");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			
			value =  reHelper.checkValue( docroot.getChild("Flag") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"Flag", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("Flag");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			
			value =  reHelper.checkValue( docroot.getChild("Obs") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"Obs", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("Obs");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			
			value =  reHelper.checkValue( docroot.getChild("EstadoInicial") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"EstadoInicial", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("EstadoInicial");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			
			value =  reHelper.checkValue( docroot.getChild("DireccionCliente") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"DireccionCliente", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("DireccionCliente");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			
			value =  reHelper.checkValue( docroot.getChild("PuestoExpedicion") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"PuestoExpedicion", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("PuestoExpedicion");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			
			value =  reHelper.checkValue( docroot.getChild("RazonSocialCliente") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"RazonSocialCliente", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("RazonSocialCliente");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
			
			value =  reHelper.checkValue( docroot.getChild("TelefonoCliente") );
			//log.debug("campo "+value);
			if (!reHelper.isCorrect(documentName,"TelefonoCliente", value )){
	            
	            MissingElementException mee = new MissingElementException();
	            mee.setElement("TelefonoCliente");
	            mee.setParent(docroot);
	            ex.addChild(mee);
			}
		
		log.debug("$$$ validando XML correctamente");	
		} catch (Exception e) {
			log.fatal("Error xml mapper"+e.toString());
		   	 ex.addChild(new  XMLMapperException(e.toString()));
		}
						//aav.
		//log.debug("Antes de cerrar"+ docroot.toString());
		log.debug("RetentionXMLMapper: Metodo : validaContenido : FIN");
	}


	
	
	/**
	 * Metodo que verifica la estructura del documento XML de RFQ por el lado del Comprador.
	 * @see com.b2mining.integration.xml.XMLMapper#parseXML(InputStream)
	 * @param stream objeto que contiene el documento XML a verificar
	 * @return clase que contiene la informacion extraida del documento XML
	 * @throws XMLMapperException
	 */
	public XMLBean parseXML(Reader stream,Reader streamAux) throws XMLMapperException {
		log.debug("Inicio XML parserXML");
	    Retention retention = null;
	    RetentionItem retentionItem = null;
	   
	    boolean hasErrors = false;
	    String dateFormat = Constantes.DATEFORMAT;
	    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);

	    Document doc = null;			
		XMLMapperException ex = new XMLMapperException();
		//.
	
		try {
			// aav Validacion de estructura y contenido
			//log.debug("Antes de validar documento "+stream.toString()+ " proba "+streamAux.toString());
			doc = validaDocumento(stream, streamAux , ex);
			//log.debug("RXML Valide documento");
			if (doc==null) {
				log.debug("Documento nulo, no sirve");
				throw ex;
			}
			// .
			// Parsing the elements into beans:
			Element docroot = doc.getRootElement();
			
			//aav 20040428
			RequiredElementHelper reHelper= new RequiredElementHelper();
			String documentName = docroot.getName();
			String value=null;
			// aav.          	
			retention = new Retention();
			
			value =  reHelper.checkValue(docroot.getChild("SerieRetencion") );
					retention.setSerieRetencion(value);

			value =  reHelper.checkValue(docroot.getChild("NumeroRetencion") );
					retention.setNumRetencion(value);
			
			value =  reHelper.checkValue(docroot.getChild("RucComprador") );
					retention.setRucComprador(value);
					
			value =  reHelper.checkValue(docroot.getChild("RucProveedor") );
					retention.setRucProveedor(value);
					
			value =  reHelper.checkValue(docroot.getChild("RazonSocialProveedor") );
					retention.setRazonSocialProveedor(value);
					
			value =  reHelper.checkValue(docroot.getChild("DireccionProveedor") );
					retention.setDireccionProveedor(value);
					
			value =  reHelper.checkValue(docroot.getChild("Fecha") );
			try{
				retention.setFechaRetencion(reHelper.parseDate(value, simpleDateFormat));
			}
			catch(Exception e){
                
                FormatException fe = new FormatException(1);
                fe.setDateFormat(dateFormat);
                fe.setElement("Fecha");
                fe.setParent(docroot);
                ex.addChild(fe);
			}
			//log.debug("Llego aqui2");	
			List retencionList = docroot.getChildren("DetalleRetencion");
			

			if (retencionList!=null){
				//log.debug("Hay elementos "+retencionList.size());
				for (int i=0;i<retencionList.size();i++){
					//log.debug("entro al for, Detalle Retencion");
					Element elementItem = (Element)retencionList.get(i);
					retentionItem = new RetentionItem();
					
		    	    value =  reHelper.checkValue( elementItem.getChild("TipoDocumento") );
							retentionItem.setTipoDocumento(value);
					
					value =  reHelper.checkValue( elementItem.getChild("SerieDocumento") );
							retentionItem.setSerieDocumento(value);
					
					value =  reHelper.checkValue( elementItem.getChild("NumeroDocumento") );
							retentionItem.setNumeroDocumento(value);
					
					value =  reHelper.checkValue(elementItem.getChild("FechaDocumento") );
					try{
						//log.debug("try ");
						retentionItem.setFechaDocumento(reHelper.parseDate(value, simpleDateFormat));
					}
					catch(Exception e){
						//log.debug("catch "+e.getMessage());
		                FormatException fe = new FormatException(1);
		                fe.setDateFormat(dateFormat);
		                fe.setElement("FechaDocumento");
		                fe.setParent(docroot);
		                ex.addChild(fe);
					}
					
					//log.debug("entro al for, Detalle Retencion1");
					value =  reHelper.checkValue(elementItem.getChild("MontoPago") );
					
					if(value!=null && !value.equalsIgnoreCase("")){
						retentionItem.setMontoPago(new Double(Double.parseDouble(value)));
						log.info("MontoPago "+value);
					}

					value =  reHelper.checkValue(elementItem.getChild("MontoRetenido") );
					if(value!=null && !value.equalsIgnoreCase("")){
						log.info("Monto Retenido "+value);
						retentionItem.setMontoRetenido(new Double(Double.parseDouble(value)));
					}
					
					value =  reHelper.checkValue(elementItem.getChild("MontoOrigen") );
					if(value!=null && !value.equalsIgnoreCase("")){
						retentionItem.setMontoOrigen(new Double(Double.parseDouble(value)));
						log.info("Monto Origen "+value);
					}
						
					value =  reHelper.checkValue( elementItem.getChild("Moneda") );
					if(value!=null && !value.equalsIgnoreCase("")){
						log.info("Moneda "+value);
						retentionItem.setMoneda(value);
					}

					value = reHelper.checkValue( elementItem.getChild("NroDocERPItem"));
					if(value!=null && !value.equalsIgnoreCase("")){
						log.info("NroDocERPItem "+value);
						retentionItem.setNroDocERPItem(value);
					}
					
					retention.addItem(retentionItem);
					//log.debug("hasta aqui");
				}
			}
			
			value =  reHelper.checkValue(docroot.getChild("TipoCambio") );
			if(value!=null && value.equalsIgnoreCase("")){
				retention.setTipoCambio(value);
				log.info("TipoCambio "+value);
			}
			
			value =  reHelper.checkValue(docroot.getChild("Banco") );
			if(value!=null && value.equalsIgnoreCase("")){
				retention.setBanco(value);
				log.info("Banco "+value);
			}
			
			value =  reHelper.checkValue(docroot.getChild("CorridaNumero") );
			if(value!=null && value.equalsIgnoreCase("")){
				retention.setCorridaNumero(value);
				log.info("CorridaNumero "+value);
			}
			
			value =  reHelper.checkValue(docroot.getChild("TotalMontoPago") );
			if(value!=null && !value.equalsIgnoreCase("")){
				//log.debug("TotalMontoPago "+String.valueOf((new Double(Double.parseDouble(value)))));
				log.info("TotalMontoPago "+value);
				retention.setTotalMontoPago(new Double(Double.parseDouble(value)));
			}

			value =  reHelper.checkValue(docroot.getChild("TotalMontoRetenido") );
			if(value!=null && !value.equalsIgnoreCase("")){
				log.info("TotalMontoRetenido "+value);
				retention.setTotalMontoRetencion(new Double(Double.parseDouble(value)));
				//log.debug("TotalMontoPago "+String.valueOf((new Double(Double.parseDouble(value)))));
			}
			
			value =  reHelper.checkValue( docroot.getChild("Moneda") );
			if(value!=null && !value.equalsIgnoreCase("")){
				retention.setMoneda(value);
				log.info("Moneda "+value);
			}
			
			value =  reHelper.checkValue( docroot.getChild("TotalMontoOrigen") );
			if(value!=null && !value.equalsIgnoreCase("")){
				retention.setTotalMontoOrigen(new Double(Double.parseDouble(value)));
				log.info("TotalMontoOrigen "+value);
			}
			
			value =  reHelper.checkValue( docroot.getChild("NroDocPagoERP") );
			if(value!=null && !value.equalsIgnoreCase("")){
				retention.setNroDocPagoERP(value);
				log.info("NroDocPagoERP "+value);
			}
			
			value =  reHelper.checkValue( docroot.getChild("Obs") );
			if(value!=null && !value.equalsIgnoreCase("")){
				retention.setObs(value);
				log.info("Obs "+value);
			}
			
			value =  reHelper.checkValue( docroot.getChild("Flag") );
			if(value!=null && !value.equalsIgnoreCase("")){
				retention.setEstado(value);
				log.info("Estado "+value);
			}
			
			value =  reHelper.checkValue( docroot.getChild("EstadoInicial") );
			if(value!=null && !value.equalsIgnoreCase("")){
				retention.setEstadoInicial(value);
				log.info("Estado Inicial "+value);
			}
			
			value =  reHelper.checkValue( docroot.getChild("DireccionCliente") );
			if(value!=null && !value.equalsIgnoreCase("")){
				retention.setDireccionCliente(value);
				log.info("DireccionCliente "+value);
			}
			
			value =  reHelper.checkValue( docroot.getChild("PuestoExpedicion") );
			if(value!=null && !value.equalsIgnoreCase("")){
				retention.setPuestoExpedicion(value);
				log.info("PuestoExpedicion  "+value);
			}
			
			value =  reHelper.checkValue( docroot.getChild("RazonSocialCliente") );
			if(value!=null && !value.equalsIgnoreCase("")){
				retention.setRazonSocialCliente(value);
				log.info("RazonSocialCliente "+value);
			}
			value =  reHelper.checkValue( docroot.getChild("TelefonoCliente") );
			if(value!=null && !value.equalsIgnoreCase("")){
				retention.setTelefonoCliente(value);
				log.info("TelefonoCliente "+value);
			}
		} 
		catch (Exception e) {
			e.printStackTrace();
		    throw new XMLMapperException("Error Parser "+e.toString());
		}
						//aav.
		try{
			log.info("Montos "+retention.getTotalMontoRetencion().doubleValue()+" "+retention.getTotalMontoPago().doubleValue());
		}
		catch(Exception m){
			log.error("Error aqui en xml "+m.getMessage());
		}
		if (ex.getChildrenCount()>0) {
			//log.debug("Otro error en el parse");
			throw ex;
		}
		//.
		if(retention!=null)
			log.info("Fin XML parserXML");
		/*else
			log.info("Fin XML parserXML nulo");*/
		return retention;
	}


	/**
	 * Metodo que genera un documento fisico XML de Factura
	 * @see com.b2mining.integration.xml.XMLMapper#parseXML(InputStream)
	 * @param message objeto que contiene el documento mensajeMQ a guardar
	 * @param ret objeto factura que sirve para obtener el nombre del nuevo documento XML
	 * @return objeto boolean que sirve para saber si se ha generado o no el documento 
	 * @throws XMLMapperException
	 */	
	public boolean registrarXML (MQIntegrationMessage message, Retention ret) throws Exception{
        log.debug("RetentionXMLMapper - registrarXML :  INICIO ");
		String nameFile = "";
		String auxliar="";
	/*	String orgid = "";
		String userid = "";
		String action ="";
		String errorCode ="";
		*/
		boolean resultado = false;
		FileWriter fw = null;
		PrintWriter out = null;
		String fileXML="";
		SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd_hhmmssSSS");
		
		try{
			nameFile = nameFile + message.getAction().trim()+"_";
			if (message.getDocNumber()!=null)
				nameFile = nameFile + message.getDocNumber().trim()+"_"; 
			nameFile = nameFile + message.getOrgId().trim()+"_";
			nameFile = nameFile + message.getOrgUserId().trim()+"_";
			
			String fechahora = dateFormatter.format(new java.util.Date());
			nameFile = nameFile +"_" +ret.getNumRetencion()+"_" +fechahora + ".xml";
			//nameFile=TXTReader.varnombre;
			log.info("nameFile del XML a guardar: "+nameFile);
			//log.debug("Accion: "+message.getAction());
			//fileXML = directorioFile(message,nameFile);
			
			//if(Helper.tipoEjecucion.equalsIgnoreCase("MultiEmpresa") && ret!=null){
				log.debug("VALOR DE AUXLIAR antes de bsucarEmpresa : "+auxliar);
				//detttttt=(Detraccion)(dc.getBean(0));
				log.debug("retttt : "+ret.getRucComprador());
				Empresa eu=new Empresa();
				eu=cargarinfoEmpresa( ret.getRucComprador())  ;
				log.debug("euuu : "+eu.getRAZONSOCIAL());
				auxliar=eu.getRAZONSOCIAL();
				log.debug("VALOR DE AUXLIAR despues de buscarEmpresa : "+auxliar);
				fileXML =fileXML+"\\"+ Helper.rutaarchivoxml+"\\"+auxliar+"\\"+Constantes.DIR_RETENCIONES+"\\"+nameFile;
			/*}else{
				fileXML =fileXML+"\\"+ Helper.rutaarchivoxml+"\\"+Helper.rutaempresa+"\\"+Constantes.DIR_RETENCIONES+"\\"+nameFile;
			}	*/
			
			//fileXML =fileXML+"\\"+ Helper.rutaarchivoxml+"\\"+Helper.rutaempresa+"\\"+Constantes.DIR_RETENCIONES+"\\"+nameFile;
			fw = new FileWriter(fileXML,false);
			out = new PrintWriter(fw);
			out.println(message.getBody());
			log.debug("### despues de crear el XML con cuerpo: " + message.getBody());
		 	log.info("Archivo XML Almacenado en: "+fileXML);	
		 	//resultado = registrarXMLBD(message,nameFile,idCheckpointIntegracion);
		 	resultado=true;
		}
		catch (Exception e){
			log.fatal("Error al registrar el XML :"+e);
			resultado = false;
			throw e;
		}
		finally {
			try {
				if (fw != null)
					fw.close();
				if (out != null)
					out.close();
					
			} 
			catch (Exception e) {
			}
		}
		return resultado;
	}



	public void generateXML(XMLBean beanList, Writer stream, int contador)
			throws XMLMapperException {
		// TODO Auto-generated method stub
		
	}



	@Override
	protected void validaContenido2(Document doc, XMLMapperException ex) {
		// TODO Auto-generated method stub
		
	}

	/*private Empresa buscarRUC(String rucc) {
		Empresa eee=new Empresa();
			for(int csm=0;csm<IntegracionSFTPMultiempresa.empresas.size();csm++){
				if(((Empresa)IntegracionSFTPMultiempresa.empresas.get(csm)).getRUC().equalsIgnoreCase(rucc)){
					eee=(Empresa)IntegracionSFTPMultiempresa.empresas.get(csm);
				}
			}
		return eee;
	}*/
	 
	private Empresa cargarinfoEmpresa(String rucCliente) {
		// TODO Auto-generated method stub
		XMLEmpresasController micont=XMLEmpresasController.getInstance();
		ArrayList<Empresa> arraybusqueda= micont.getEmpresas();
		if (arraybusqueda.size()>0)
			log.debug("tamao de arraybusqueda: "+arraybusqueda.size());
		Empresa temporal=new Empresa();
		
		if(rucCliente.length()==11){
			for(int g=0;g<arraybusqueda.size();g++){
				log.debug("comparando >>> arraybusqueda.get(g).getRUC():"+arraybusqueda.get(g).getRUC().substring(2)+" y rucCliente: "+rucCliente);
				if(arraybusqueda.get(g).getRUC().substring(2).equalsIgnoreCase(rucCliente)){
					temporal= arraybusqueda.get(g);
					break;
				}	
			}
		}else if(rucCliente.length()==13){
			for(int g=0;g<arraybusqueda.size();g++){
				log.debug("comparando >>> arraybusqueda.get(g).getRUC():"+arraybusqueda.get(g).getRUC()+" y rucCliente: "+rucCliente);
				if(arraybusqueda.get(g).getRUC().equalsIgnoreCase(rucCliente)){
					temporal= arraybusqueda.get(g);
					break;
				}	
			}
		}
		
		log.debug("sabeeeeeee: "+temporal.getRAZONSOCIAL());
		return temporal;
	}

}
